﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using ZJGIS.Framework;
using ZJGIS.Report.form;
using ZJGIS.Report.model;
using ZJGIS.EngineControl;
using ZJGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;

namespace ZJGIS.Report.button
{
    /// <summary>
    /// 说明：该类是为用户指定的房屋类型进行统计。
    /// 编写者：张忠胜
    /// 编写时间：2010.7.28
    /// </summary>
    internal class NewHouseStatButton : BaseDrawPolygonTool
    {
        private IElement m_pElement;
        private StatisticReport m_pReport;
        private IFeatureLayer pFeatureLayer;
        //private AxMapControl pMapControl;
        private string strID = "居民地面";
        private StatLayer m_pStatLyr = null;
        private DataTable m_pTable = null;
        IApplication m_Application = null;
        IMapControl3 pMapControl = null;

        public NewHouseStatButton()
        {
            base.m_caption = "房屋拆迁量统计ext";
            base.m_toolTip = base.m_caption;
        }

        public override void OnCreate(object hook)
        {
            m_Application = hook as IApplication;
            base.OnCreate(hook);
        }

        public override bool Enabled
        {
            get
            {

                if ((m_Application as IFramework).IsMapCtrlactive)
                {
                    IEnumLayer layers = (m_Application.Document as IMxDocument).ActiveView.FocusMap.get_Layers(null, true);
                    ILayer layer = layers.Next();
                    while (layer != null)
                    {
                        if (layer is IFeatureLayer)
                        {
                            Marshal.ReleaseComObject(layers);
                            return true;
                        }
                        layer = layers.Next();
                    }
                    Marshal.ReleaseComObject(layers);
                }
                return false;
            }
        }

        public override int Bitmap
        {
            get
            {
                string bitmapResourceName = "ZJGIS.Report.Res." + this.GetType().Name + ".png";
                System.IO.Stream s = GetType().Assembly.GetManifestResourceStream(bitmapResourceName);
                if (s == null) return 0;
                return new Bitmap( s ).GetHbitmap().ToInt32(); 
            }
        }

        public override void OnClick()
        {
            //if ((m_Application as IFramework).Tool == this) return;
            base.OnClick();

            if ((m_Application as IFramework).IsMapCtrlactive)
                pMapControl = (m_Application as IFramework).MapControl;
            else
                return;

            if (pMapControl == null || pMapControl.Map.LayerCount == 0) return;

            m_pStatLyr = StatFactory.GetLayerByID(strID);
            if (m_pStatLyr == null)
            {
                ControlUtility.ShowInfomationMsgbox("尚未找到房屋面层，请加载房屋面层！");
                return;
            }
            pFeatureLayer = CartoUtility.FindFeatureLayerByName(pMapControl.Map, m_pStatLyr.Value);
            if (pFeatureLayer == null)
            {
                ControlUtility.ShowInfomationMsgbox("尚未找到房屋面层，请加载房屋面层！");
                return;
            }
            m_cursor = Cursors.Cross;
        }

        public override void OnDblClick()
        {
            base.OnDblClick();
            FrmHouseStatPara house = new FrmHouseStatPara();
            house.Layer  =m_pStatLyr;
            house.ShowDialog();
            if (house.DialogResult  == DialogResult.OK)
            {
                if (pFeatureLayer == null) { return; }
                if (m_geom == null || m_geom.IsEmpty) { return; }
                if (m_pTable == null)
                {
                    m_pTable = CreateHouseDatatable();
                }
                else if (m_pTable.Rows.Count > 0)
                {
                    m_pTable.Rows.Clear();
                }

                IPolygon pPolygon = m_geom as IPolygon;
                ITopologicalOperator2 pTopo = pPolygon as ITopologicalOperator2;
                pTopo.IsKnownSimple_2 = false;
                pTopo.Simplify();
                pTopo.IsKnownSimple_2 = true;
                pPolygon.Project(GetSpatialReferenceByFeatureClass(pFeatureLayer.FeatureClass));
                Application.DoEvents();
                ISpatialFilter pSF = new SpatialFilterClass();
                pSF.Geometry = pPolygon;
                pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                pSF.WhereClause =house.WhereClause ;
                IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(pSF, false);
                IFeature pFeature = pFeatureCursor.NextFeature();
                while (pFeature != null)
                {
                    AddDatarow(m_pTable, pFeature, pPolygon);
                    pFeature = pFeatureCursor.NextFeature();
                }
                if (m_pTable.Rows.Count == 0)
                {
                    ControlUtility.ShowInfomationMsgbox("尚未检索到房屋面要素，请重试！");
                    pMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                    return;
                }
                
                if (m_pReport == null || m_pReport.IsDisposed)
                {
                    m_pReport = new StatisticReport();
                }
                m_pReport.AddConnectDatatable = m_pTable;
                m_pReport.ReportName = "房屋拆迁量统计报表.rpt";
                m_pReport.ShowDialog();
                m_pReport.RefreshReport();
            }
            pMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
        }
 

        private DataTable CreateHouseDatatable()
        {
            DataTable pTable = new DataTable();

            foreach (ReportField  field in m_pStatLyr.ReportFields)
            {
                DataColumn pColumn = new DataColumn(field.Key);
                pColumn.DataType = Type.GetType("System." + field.Type);
                if (field.Type.ToLower().Contains("int"))
                {
                    pColumn.DefaultValue = 0;
                }
                else if (field.Type.ToLower().Contains("double"))
                {
                    pColumn.DefaultValue = 0.00;
                }
                pTable.Columns.Add(pColumn);
            }
            DataColumn pColumn1 = new DataColumn("NAME");
            pColumn1.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn1);
            return pTable;
        }

        private void AddDatarow(DataTable pTable, IFeature pFeature, IPolygon pGeo)
        {
            if (pFeature == null || pTable == null) { return; }
            DataRow pRow = pTable.NewRow();
            IFields PFields = pFeature.Fields;
            int idx = -1;
            foreach (ReportField  field in m_pStatLyr.ReportFields )
            {
                switch (field.Key)
                {
                    case "OID":
                        pRow[field.Key] = pFeature.OID.ToString();
                        break;
                    case "FCODE":
                        idx = pFeature.Fields.FindField(field.Value);
                        if (idx > -1)
                        {
                            pRow[field.Key] = pFeature.get_Value(idx).ToString();
                        }
                        break;
                    case "CONSTRUCT":
                        idx = pFeature.Fields.FindField(field.Value);
                        if (idx > -1)
                        {
                            if (pFeature.get_Value(idx) == null || Convert.IsDBNull(pFeature.get_Value(idx)))
                            {
                                pRow[field.Key] = "";
                            }
                            else
                            {
                                pRow[field.Key] = pFeature.get_Value(idx).ToString();
                            }
                        }
                        break;
                    case "FLOOR":
                        idx = pFeature.Fields.FindField(field.Value);
                        if (idx > -1)
                        {
                            if (pFeature.get_Value(idx) == null || Convert.IsDBNull(pFeature.get_Value(idx)))
                            {
                                pRow[field.Key] = 1;
                            }
                            else
                            {
                                pRow[field.Key] = Convert.ToInt32(pFeature.get_Value(idx).ToString());
                            }
                        }
                        break;
                    case "AREA":
                        IPolygon pPolygon = pFeature.ShapeCopy as IPolygon;
                        IArea pArea = pPolygon as IArea;
                        pRow[field.Key] = Math.Abs(pArea.Area);
                        pRow["INTERSECTAREA"] = GetIntersectArea(pPolygon, pGeo);
                        break;
                    default:
                        break;
                }
            }

            pTable.Rows.Add(pRow);
        }

        private ISpatialReference GetSpatialReferenceByFeatureClass(IFeatureClass pClass)
        {
            try
            {
                int index = pClass.FindField(pClass.ShapeFieldName);
                IGeometryDef pGeoDef = pClass.Fields.get_Field(index).GeometryDef;
                return pGeoDef.SpatialReference;
            }
            catch (Exception ex)
            {
                ISpatialReference pSR = new UnknownCoordinateSystemClass();
                Console.WriteLine(ex.Message);
                return pSR;
            }
        }

        private double GetIntersectArea(IPolygon pPg, IPolygon oriGeo)
        {
            try
            {
                oriGeo.Project(pPg.SpatialReference);
                IRelationalOperator pRela = oriGeo as IRelationalOperator;
                if (pRela.Contains(pPg))
                {
                    IArea pArea = pPg as IArea;
                    return Math.Abs(pArea.Area);
                }
                else if (pRela.Overlaps(pPg))
                {
                    ITopologicalOperator pTopo = pPg as ITopologicalOperator;
                    IPolygon pTempGeo = pTopo.Intersect(oriGeo, pPg.Dimension) as IPolygon;
                    if (pTempGeo == null || pTempGeo.IsEmpty)
                    {
                        return 0;
                    }
                    else
                    {
                        IArea pArea = pTempGeo as IArea;
                        return Math.Abs(pArea.Area);
                    }
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ce)
            {
                return 0;
            }
        }

    }
}
